package AdminDB;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;

import DataConnectionInterface.*;
import DatabaseManager.DBManager;
import Helper.*;
import Other.*;

/**
 *
 * @author Tomy
 */
public class ServerGUI {

    private Shell shell;
    private Image background;
    private List universeList;
    private Font textFont;
    private Font universeFont;
    private Table table;
    private TableEditor editor;
    private Text universeListText;
    private Text cardListText;
    private Text screenTitle;
    private Button quitButton;
    private Button reloadDataBaseButton;
    private Button removeUniverseButton;
    private Button addUniverseButton;
    private Button addCardButton;
    private Button removeCardButton;
    private Button listNextButton;
    private Button listPrevButton;
    private Button loadUniverseCardsButton;
    private Button viewUsersButton;
    private Button tableNextButton;
    private Button tablePrevButton;    

    private UniverseList universes;
    private Universe loadedUniverse;    
    
    private boolean loading = false;
    
    //Constants:
    private final int tableCardsToDisplay = 10;
    public static int universesPerDisplay;
    public static String characterDump;
    public static String universeDump;
    private final int ATTACK_MAX = 10;
    private final int ATTACK_MIN = 1;
    private final int DEFENSE_MAX = 10;
    private final int DEFENSE_MIN = 1;
    private final int WIDTH = 750;
    private final int HEIGHT = 600;

    public ServerGUI(Shell shell) {
        FormLayout layout = new FormLayout();
        this.shell = shell;
        this.background = new Image(shell.getDisplay(), "gray.png");
        shell.setBackgroundImage(background);
        shell.setBounds(5, 5, WIDTH, HEIGHT);
        shell.setText("Universe administrator");
        shell.setLocation(5, 5);
        shell.setLayout(layout);
        this.textFont = new Font(shell.getDisplay(), "Arial", 12, SWT.ITALIC | SWT.BOLD);
        this.universeFont = new Font(shell.getDisplay(), "Calibri", 12, SWT.NORMAL);
        initUniverses();
        initList();
        initTable();
        addTableListener();
        initText();
        initButtons();
    }

    /*  Functions u need to implement/modify
     *
     *  Starting here:
     */
    private void saveChangesToTable(String name, String attack, String defense, int index) {
        TableItem item = table.getItem(index);
        item.setText(0, name);
        item.setText(1, attack);
        item.setText(2, defense);
        loadedUniverse.updateCard(new ServerCardConcrete(name,
                Integer.parseInt(attack), Integer.parseInt(defense)), index);
    }

    private void removeCardButtonLogic() {
        
        final Display display = Display.getDefault();
    	final Shell waitShell = new Shell(display, SWT.NO_REDRAW_RESIZE);
    	new WaitMessage(waitShell, "Waiting for Database...");
    	waitShell.open();
    	waitShell.setLocation(250, 250);
    	
    	Thread execDB = new Thread(new Runnable(){
    		public void run(){
    			display.asyncExec(new Runnable(){

    				@Override
    				public void run() {
    					int tableIndex = table.getSelectionIndex();        
    			        loadedUniverse.removeCard(tableIndex);
    			        waitShell.close();
    			        populateTable();
    				}
    	    		
    	    	});
    		}
    	});
    	execDB.start();
    	
        while(!waitShell.isDisposed()){
        	if(!waitShell.getDisplay().readAndDispatch()){
        		waitShell.getDisplay().sleep();
        	}
        }
    }

    private void populateTable() {
        table.removeAll();
        for (int i = 0; (i < loadedUniverse.getNumOfCards()); ++i) {            
            ServerCard card = loadedUniverse.getCard(i);
            TableItem item = new TableItem(table, SWT.NONE);
            item.setText(0, card.getName());
            item.setText(1, card.getAttack().toString());
            item.setText(2, card.getDefense().toString());
        }
    }

    /*u need to implement this*/
    private void loadCardsButtonLogic() { 
    	final Display display = Display.getDefault();
     	final Shell waitShell = new Shell(display, SWT.NO_REDRAW_RESIZE);
     	new WaitMessage(waitShell, "Waiting for Database...");
     	waitShell.open();
     	waitShell.setLocation(250, 250);
     	
    	Thread execDB = new Thread(new Runnable(){
    		public void run(){
    			display.asyncExec(new Runnable(){
    				public void run(){
    					int listIndex = universeList.getSelectionIndex();
    			        loadedUniverse = universes.getUniverse(listIndex);
    			        loadedUniverse.loadCurrentPage();
    			        waitShell.close();
    			        populateTable();
    			        table.setToolTipText("Double-click to edit");
    				}
    			});
    		}
    	});
     	execDB.start();
     	
     	while(!waitShell.isDisposed()){
        	if(!waitShell.getDisplay().readAndDispatch()){
        		waitShell.getDisplay().sleep();
        	}
        }
    }

    /*u need to implement this*/
    private void addCardButtonLogic(final String name, final String attack, final String defense) {
    	final Display display = Display.getDefault();
     	final Shell waitShell = new Shell(display, SWT.NO_REDRAW_RESIZE);
     	new WaitMessage(waitShell, "Waiting for Database...");
     	waitShell.open();
     	waitShell.setLocation(250, 250);
    	
     	Thread execDB = new Thread(new Runnable(){
     		public void run(){
     			display.asyncExec(new Runnable(){
     				@Override
     				public void run() {
     					loadedUniverse.addCard(new ServerCardConcrete(name,
     			                Integer.parseInt(attack), Integer.parseInt(defense)));
     			        waitShell.close();
     					populateTable();
     			
     				}    	     		
     	     	});
     		}
     	});
     	execDB.start();
     	
     	while(!waitShell.isDisposed()){
        	if(!waitShell.getDisplay().readAndDispatch()){
        		waitShell.getDisplay().sleep();
        	}
        }
    }

    private void initUniverses() {
        this.universes = new UniverseListConcrete(universesPerDisplay);
        this.loadedUniverse = null;
    }

    private void populateList(List list) {
        list.removeAll();

        for (int i = 0; i < universes.getNumOfUniverses() ; ++i) {
            list.add(universes.getUniverse(i).getName());
        }
    }

    private void viewUsersButtonLogic() {
        Display display = Display.getDefault();
        Shell usersShell = new Shell(display, SWT.MENU);
        new UsersGui(usersShell);
        usersShell.open();
        while (!usersShell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
    }

    private void addUniverseButtonLogic(final String universe) {
    	final Display display = Display.getDefault();
     	final Shell waitShell = new Shell(display, SWT.NO_REDRAW_RESIZE);
     	new WaitMessage(waitShell, "Waiting for Database...");
     	waitShell.open();
     	waitShell.setLocation(250, 250);
    	
     	Thread execDB = new Thread(new Runnable(){
     		public void run(){
     			display.asyncExec(new Runnable(){

     				@Override
     				public void run() {
     					universes.addUniverse(new UniverseConcrete(universe));
     			        waitShell.close();
     					populateList(universeList);	
     				}
     	     		
     	     	});
     		}
     	});
     	execDB.start();
        
        while(!waitShell.isDisposed()){
        	if(!waitShell.getDisplay().readAndDispatch()){
        		waitShell.getDisplay().sleep();
        	}
        }
    }
    
    private void removeUniverseButtonLogic() {
    	final Display display = Display.getDefault();
     	final Shell waitShell = new Shell(display, SWT.NO_REDRAW_RESIZE);
     	new WaitMessage(waitShell, "Waiting for Database...");
     	waitShell.open();
     	waitShell.setLocation(250, 250);
     	
     	Thread execDB = new Thread(new Runnable(){
     		public void run(){
     			display.asyncExec(new Runnable(){

     				@Override
     				public void run() {
     					int listPos = universeList.getSelectionIndex();
     			        universes.removeUniverse(listPos);
     			        waitShell.close();
     			        populateList(universeList);
     				}
     	     		
     	     	});
     		}
     	});
     	execDB.start();
        
     	while(!waitShell.isDisposed()){
         	if(!waitShell.getDisplay().readAndDispatch()){
         		waitShell.getDisplay().sleep();
         	}
        }
     	 
        table.removeAll();
        table.setToolTipText("First select a universe to edit");
    }

    /*u need to implement this*/
    private void databaseReloadLogic() {
    	final Display display = Display.getDefault();
     	final Shell waitShell = new Shell(display, SWT.NO_REDRAW_RESIZE);
     	new WaitMessage(waitShell, "Waiting for Database...");
     	waitShell.open();
     	waitShell.setLocation(250, 250);
     	
     	Thread execDB = new Thread(new Runnable(){
			@Override
			public void run() {
				display.asyncExec(new Runnable(){
					@Override
					public void run() {
						ConnectionPool pool = null;
						GameDataConnectionInterface con = null;
						try {
							pool = ConnectionPool.getInstance();
							con = pool.getConnection();
							con.CreateDataBase(characterDump, universeDump);
							waitShell.close();
							shell.setVisible(true);
							pool.returnConnection(con);
						} catch (GameException e) {
							if(pool != null && con != null)  pool.returnConnection(con);
						}
					}		     		
		     	});				
			}    		
     	});
     	execDB.start();
        
     	while(!waitShell.isDisposed()){
         	if(!waitShell.getDisplay().readAndDispatch()){
         		waitShell.getDisplay().sleep();
         	}
        }
     	 
     	initUniverses();
     	populateList(universeList);
    }

    /*u need to implement this*/
    private void quitButtonLogic() {
        System.exit(0);

    }

    private void listNextButtonLogic() {
    	final Display display = Display.getDefault();
     	final Shell waitShell = new Shell(display, SWT.NO_REDRAW_RESIZE);
     	new WaitMessage(waitShell, "Waiting for Database...");
     	waitShell.open();
     	waitShell.setLocation(250, 250);
     	
     	Thread execDB = new Thread(new Runnable(){
     		public void run(){
     			display.asyncExec(new Runnable(){
  				@Override
     				public void run() {
  						universes.toNextPage();
  						waitShell.close();
  						populateList(universeList);
     				}  	     		
     	     	});
     		}
     	});
     	execDB.start();
        
     	while(!waitShell.isDisposed()){
         	if(!waitShell.getDisplay().readAndDispatch()){
         		waitShell.getDisplay().sleep();
         	}
        }
    	 	
    }

    private void listPrevButtonLogic() {
    	final Display display = Display.getDefault();
     	final Shell waitShell = new Shell(display, SWT.NO_REDRAW_RESIZE);
     	new WaitMessage(waitShell, "Waiting for Database...");
     	waitShell.open();
     	waitShell.setLocation(250, 250);
     	
     	Thread execDB = new Thread(new Runnable(){
     		public void run(){
     			display.asyncExec(new Runnable(){
  				@Override
     				public void run() {
	  					universes.toPreviousPage();
	  					waitShell.close();
	  			        populateList(universeList);
     				}  	     		
     	     	});
     		}
     	});
     	execDB.start();
        
     	while(!waitShell.isDisposed()){
         	if(!waitShell.getDisplay().readAndDispatch()){
         		waitShell.getDisplay().sleep();
         	}
        }
    	
    }

    private void cardsPrevButtonLogic() {
    	final Display display = Display.getDefault();
     	final Shell waitShell = new Shell(display, SWT.NO_REDRAW_RESIZE);
     	new WaitMessage(waitShell, "Waiting for Database...");
     	waitShell.open();
     	waitShell.setLocation(250, 250);
     	
     	Thread execDB = new Thread(new Runnable(){
     		public void run(){
     			display.asyncExec(new Runnable(){
  				@Override
     				public void run() {
	  					if (null != loadedUniverse) {
	  			        	loadedUniverse.toPreviousPage();
	  			        	waitShell.close();
	  			            populateTable();
	
	  			        }
     				}  	     		
     	     	});
     		}
     	});
     	execDB.start();
        
     	while(!waitShell.isDisposed()){
         	if(!waitShell.getDisplay().readAndDispatch()){
         		waitShell.getDisplay().sleep();
         	}
        }
    	
        
    }

    private void cardsNextButtonLogic() {
    	
    	final Display display = Display.getDefault();
     	final Shell waitShell = new Shell(display, SWT.NO_REDRAW_RESIZE);
     	new WaitMessage(waitShell, "Waiting for Database...");
     	waitShell.open();
     	waitShell.setLocation(250, 250);
     	
     	Thread execDB = new Thread(new Runnable(){
     		public void run(){
     			display.asyncExec(new Runnable(){
  				@Override
     				public void run() {
     					if (null != loadedUniverse) {
     			        	loadedUniverse.toNextPage();
     			        	waitShell.close();
     			            populateTable();

     			        }
     				}  	     		
     	     	});
     		}
     	});
     	execDB.start();
        
     	while(!waitShell.isDisposed()){
         	if(!waitShell.getDisplay().readAndDispatch()){
         		waitShell.getDisplay().sleep();
         	}
        }
    	
    	
        
    }
    /*
     * **************** * **************** * ****************
     */
    /*  logic related functions, u can modify/remove
     *
     *
     */
    private boolean containsRealTextInput(String in) {
        for (int i = 0; i < in.length(); ++i) {
            char c = in.charAt(i);
            if ((' ' == c) || ('\n' == c) || ('\t' == c)) {
                continue;
            } else {
                return true;
            }
        }
        return false;
    }

    private boolean isNum(char c) {
        if (('0' <= c) && ('9' >= c)) {
            return true;
        } else {
            return false;
        }
    }

    private boolean isStringANumber(String num) {
        for (int i = 0; i < num.length(); ++i) {
            if (!isNum(num.charAt(i))) {
                return false;
            }
        }
        return true;
    }

    private boolean isNumberInAttackRange(Integer num) {
        if ((ATTACK_MIN <= num) && (ATTACK_MAX >= num)) {
            return true;
        } else {
            return false;
        }
    }

    private boolean isNumberInDefenseRange(Integer num) {
        if ((DEFENSE_MIN <= num) && (DEFENSE_MAX >= num)) {
            return true;
        } else {
            return false;
        }
    }


    /*
     * **************** * **************** * ****************
     */
    /*  Gui related functions
     *
     *
     */
    private void showError(Shell shell, String errString) {
        MessageBox mb = new MessageBox(shell, SWT.ICON_ERROR | SWT.OK);
        mb.setMessage(errString);
        mb.setText("Unable to save changes");
        mb.open();
    }

    private FormData locateButton(int width, int height, int top1, int top2,
            int left1, int left2) {
        FormData result = new FormData(width, height);
        result.top = new FormAttachment(top1, top2);
        result.left = new FormAttachment(left1, left2);
        return result;
    }

    private void initButtons() {
        this.tablePrevButton = new Button(shell, SWT.PUSH);
        tablePrevButton.setText("<");
        FormData tablePrevButtonFD = locateButton(30, 20, 83, 69, 86, 25);
        tablePrevButton.setLayoutData(tablePrevButtonFD);
        tablePrevButton.setToolTipText("View previous batch of cards");


        this.tableNextButton = new Button(shell, SWT.PUSH);
        tableNextButton.setText(">");
        FormData tableNextButtonFD = locateButton(30, 20, 83, 69, 90, 25);
        tableNextButton.setLayoutData(tableNextButtonFD);
        tableNextButton.setToolTipText("View next batch of cards");

        this.viewUsersButton = new Button(shell, SWT.FLAT);
        viewUsersButton.setText("View/Edit Users");
        FormData viewUsersButtonFD = locateButton(110, 30, 80, 69, 5, 15);
        viewUsersButton.setLayoutData(viewUsersButtonFD);
        viewUsersButton.setToolTipText("Click to view and edit users");

        this.loadUniverseCardsButton = new Button(shell, SWT.FLAT);
        loadUniverseCardsButton.setText("Load Cards");
        FormData loadUniverseCardsButtonFD = locateButton(100, 30, 80, 69, 23, 35);
        loadUniverseCardsButton.setLayoutData(loadUniverseCardsButtonFD);
        loadUniverseCardsButton.setToolTipText("Loads cards for selected universe");

        this.listNextButton = new Button(shell, SWT.FLAT);
        listNextButton.setText("Next");
        FormData listNextButtonFD = locateButton(100, 30, 80, 36, 23, 35);
        listNextButton.setLayoutData(listNextButtonFD);
        listNextButton.setToolTipText("Click to show next batch of universes");

        this.listPrevButton = new Button(shell, SWT.FLAT);
        listPrevButton.setText("Previous");
        FormData listPrevButtonFD = locateButton(110, 30, 80, 36, 5, 15);
        listPrevButton.setLayoutData(listPrevButtonFD);
        listPrevButton.setToolTipText("Click to show previous batch of universes");

        this.addCardButton = new Button(shell, SWT.FLAT);
        addCardButton.setText("Add card");
        FormData addCardButtonFD = locateButton(70, 30, 44, 60, 20, 15);
        addCardButton.setLayoutData(addCardButtonFD);
        addCardButton.setToolTipText("Add a new card to the selected universe");

        this.removeCardButton = new Button(shell, SWT.FLAT);
        removeCardButton.setText("Delete card");
        FormData removeCardButtonFD = locateButton(85, 30, 44, 60, 30, 15);
        removeCardButton.setLayoutData(removeCardButtonFD);
        removeCardButton.setToolTipText("Remove card from selected universe");

        this.addUniverseButton = new Button(shell, SWT.FLAT);
        addUniverseButton.setText("Add universe");
        FormData addUniverseButtonFD = locateButton(125, 30, 38, 60, 22, 15);
        addUniverseButton.setLayoutData(addUniverseButtonFD);
        addUniverseButton.setToolTipText("Create a new universe");

        this.removeUniverseButton = new Button(shell, SWT.FLAT);
        removeUniverseButton.setText("Delete universe");
        FormData removeUniverseButtonFD = locateButton(125, 30, 38, 60, 5, 15);
        removeUniverseButton.setLayoutData(removeUniverseButtonFD);
        removeUniverseButton.setToolTipText("Removes selected universe from the database");

        this.reloadDataBaseButton = new Button(shell, SWT.FLAT);
        reloadDataBaseButton.setText("Reload Database");
        FormData reloadDataBaseButtonFD = locateButton(110, 30, 1, 0, 70, 15);
        reloadDataBaseButton.setLayoutData(reloadDataBaseButtonFD);
        reloadDataBaseButton.setToolTipText("Reloads all the universes from the Database");

        this.quitButton = new Button(shell, SWT.FLAT);
        quitButton.setText("Exit");
        FormData quitButtonFD = locateButton(60, 30, 1, 0, 87, 15);
        quitButton.setLayoutData(quitButtonFD);
        quitButton.setToolTipText("Click to exit screen");

        quitButton.addSelectionListener(new SelectionListener() {

            public void widgetSelected(SelectionEvent e) {
                quitButtonLogic();
            }

            public void widgetDefaultSelected(SelectionEvent e) {
            }
        });

        reloadDataBaseButton.addSelectionListener(new SelectionListener() {

            public void widgetSelected(SelectionEvent e) {
                MessageBox mb = new MessageBox(shell, SWT.ICON_WARNING | SWT.OK | SWT.CANCEL);
                mb.setMessage("Are you sure? This could take a couple of minutes");
                mb.setText("Reload data confirmation");
                int userSelect = mb.open();
                if (SWT.OK == userSelect) {
                	shell.getDisplay().asyncExec(new Runnable(){
						@Override
						public void run() {
							databaseReloadLogic();
						}               		
                	});
                	
                }

            }

            public void widgetDefaultSelected(SelectionEvent e) {
            }
        });

        // done
        removeUniverseButton.addSelectionListener(new SelectionListener() {

            public void widgetSelected(SelectionEvent e) {
                if (universeList.getSelection().length > 0) {
                    MessageBox removeMB = new MessageBox(shell, SWT.ICON_WARNING | SWT.OK | SWT.CANCEL);
                    removeMB.setMessage("Delete " + universeList.getSelection()[0] + " ?");
                    removeMB.setText("Delete universe confirmation");
                    int userSelect = removeMB.open();
                    if (SWT.OK == userSelect) {
                    	shell.getDisplay().asyncExec(new Runnable(){
                    		public void run(){
                    			 removeUniverseButtonLogic();
                    		}
                    	});    
                    }
                }
            }

            public void widgetDefaultSelected(SelectionEvent e) {
            }
        });

        // done
        addUniverseButton.addSelectionListener(new SelectionListener() {

            public void widgetSelected(SelectionEvent e) {
                new DialogAddUniverse();
            }

            public void widgetDefaultSelected(SelectionEvent e) {
            }
        });

        // done
        addCardButton.addSelectionListener(new SelectionListener() {

            public void widgetSelected(SelectionEvent e) {
                if (universeList.getSelectionCount() > 0) {
                    if (null != loadedUniverse) {
                        new DialogAddCard();
                    }
                }
            }

            public void widgetDefaultSelected(SelectionEvent e) {
            }
        });

        // done
        removeCardButton.addSelectionListener(new SelectionListener() {

            public void widgetSelected(SelectionEvent e) {
                if (table.getSelection().length > 0) {
                	shell.getDisplay().asyncExec(new Runnable(){
                		public void run(){
                			 removeCardButtonLogic();
                		}
                	});
                   
                }
            }

            public void widgetDefaultSelected(SelectionEvent e) {
            }
        });
        
        // done
        this.tableNextButton.addSelectionListener(new SelectionListener() {

            public void widgetSelected(SelectionEvent e) {
            	shell.getDisplay().asyncExec(new Runnable(){
            		public void run(){
            			 cardsNextButtonLogic();
            		}
            	});
            }

            public void widgetDefaultSelected(SelectionEvent e) {
            }
        });

        // done
        this.tablePrevButton.addSelectionListener(new SelectionListener() {

            public void widgetSelected(SelectionEvent e) {
            	shell.getDisplay().asyncExec(new Runnable(){
            		public void run(){
            			 cardsPrevButtonLogic();
            		}
            	});
               
            }

            public void widgetDefaultSelected(SelectionEvent e) {
            }
        });

        // done
        listNextButton.addSelectionListener(new SelectionListener() {

            public void widgetSelected(SelectionEvent e) {
            	shell.getDisplay().asyncExec(new Runnable() {					
					@Override
					public void run() {
						listNextButtonLogic();
					}
				});             
            }

            public void widgetDefaultSelected(SelectionEvent e) {
            }
        });

        // done
        listPrevButton.addSelectionListener(new SelectionListener() {

            public void widgetSelected(SelectionEvent e) {
            	shell.getDisplay().asyncExec(new Runnable(){
            		public void run(){
            			listPrevButtonLogic();
            		}
            	});              
            }

            public void widgetDefaultSelected(SelectionEvent e) {
            }
        });

        this.loadUniverseCardsButton.addSelectionListener(new SelectionListener() {

            public void widgetSelected(SelectionEvent e) {
                if (universeList.getSelection().length > 0) {
                	shell.getDisplay().asyncExec(new Runnable(){
                		public void run(){
                			 loadCardsButtonLogic();
                		}
                	});
                }
            }

            public void widgetDefaultSelected(SelectionEvent e) {
            }
        });

        viewUsersButton.addSelectionListener(new SelectionListener() {

            public void widgetSelected(SelectionEvent e) {
                viewUsersButtonLogic();
            }

            public void widgetDefaultSelected(SelectionEvent e) {
            }
        });
    }

    private void initText() {
        this.screenTitle = new Text(shell, SWT.READ_ONLY);
        screenTitle.setFont(new Font(shell.getDisplay(), "Arial", 21, SWT.BOLD | SWT.ITALIC));
        screenTitle.setText("\n\n\n Universe\n Administrator\n screen");
        screenTitle.setBounds(0, 0, 120, 25);
        FormData titleFD = locateButton(320, 247, 0, 0, 0, 0);
        screenTitle.setLayoutData(titleFD);
        screenTitle.setBackgroundImage(background);

        this.universeListText = new Text(shell, SWT.READ_ONLY);
        universeListText.setFont(textFont);
        universeListText.setText("Universe list:");
        universeListText.setBounds(0, 0, 120, 25);
        FormData universeListTextFD = locateButton(100, 17, 55, 6, 5, 15);
        universeListText.setLayoutData(universeListTextFD);

        this.cardListText = new Text(shell, SWT.READ_ONLY);
        cardListText.setFont(textFont);
        cardListText.setText("Cards list:");
        cardListText.setBounds(0, 0, 120, 25);
        FormData cardListTextFD = locateButton(80, 17, 5, 6, 47, 5);
        cardListText.setBackgroundImage(new Image(shell.getDisplay(), "cardListTextBg.png"));
        cardListText.setLayoutData(cardListTextFD);
    }

    private void initList() {
        this.universeList = new List(shell, SWT.SINGLE | SWT.V_SCROLL | SWT.BORDER);
        FormData playersListDB = locateButton(230, 144, 55, 30, 5, 15);
        universeList.setLayoutData(playersListDB);
        universeList.setFont(universeFont);
        universeList.setBackground(new Color(shell.getDisplay(), 240, 240, 205));
        universeList.setToolTipText("Select universe to edit");
        populateList(universeList);
    }

    private void initTable() {
        this.table = new Table(shell, SWT.SINGLE | SWT.BORDER | SWT.VIRTUAL | SWT.FULL_SELECTION);
        table.setLinesVisible(true);
        table.setHeaderVisible(true);
        table.setFont(universeFont);
        FormData tableFD = locateButton(360, 438, 5, 30, 45, 15);
        table.setLayoutData(tableFD);
        String[] titles = {"Name", "Attack", "Defense"};
        for (int i = 0; i < titles.length; i++) {
            TableColumn column = new TableColumn(table, SWT.NONE);
            column.setText(titles[i]);
        }
        for (int i = 1; i < titles.length; i++) {
            table.getColumn(i).pack();
        }
        table.getColumn(0).setWidth(220);
        this.editor = new TableEditor(table);
        editor.horizontalAlignment = SWT.LEFT;
        editor.grabHorizontal = true;
        table.setToolTipText("Once a universe is selected, you can start editing it");

    }

    private void addTableListener() {
        table.addSelectionListener(new SelectionListener() {

            public void widgetSelected(SelectionEvent e) {
            }

            public void widgetDefaultSelected(SelectionEvent e) {
                if (table.getSelection().length > 0) {
                    TableItem item = table.getSelection()[0];
                    String name = item.getText(0);
                    String attack = item.getText(1);
                    String defense = item.getText(2);
                    new DialogAddCard(name, attack, defense, table.getSelectionIndex());
                }

            }
        });
    }

    /*
     * **************** * **************** * ****************
     */
    /*  private classes: add universe shell dialog
     *                   add card to universe dialog
     *
     *
     */
    private class DialogAddUniverse {

        private Text universeName;
        private Label universeNameLabel;

        private DialogAddUniverse() {
            Display display = shell.getDisplay();
            final Shell shell = new Shell(display);
            shell.setLayout(new GridLayout(5, false));
            shell.setText("Add Universe");
            universeNameLabel = new Label(shell, SWT.NULL);
            universeNameLabel.setText("Universe name:");
            universeName = new Text(shell, SWT.SINGLE | SWT.BORDER);
            universeName.setText("");
            universeName.setTextLimit(30);
            universeName.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
            Button button = new Button(shell, SWT.PUSH);
            button.setText("Submit");
            button.setToolTipText("Click to add universe");
            button.addSelectionListener(new SelectionListener() {

                public void widgetSelected(SelectionEvent e) {
                    final String result = universeName.getText();
                    if (!result.isEmpty()) {
                    	shell.getDisplay().asyncExec(new Runnable(){
                    		public void run(){
                    			 if (containsRealTextInput(result)) {
                                     addUniverseButtonLogic(result);
                                     shell.close();
                                 } else {
                                     showError(shell, "Input contains only whitespace text");
                                 }
                    		}
                    	});
                       
                    } else {
                        showError(shell, "No input recieved");
                    }
                }

                public void widgetDefaultSelected(SelectionEvent e) {
                }
            });
            shell.pack();
            shell.open();
            while (!shell.isDisposed()) {
                if (!display.readAndDispatch()) {
                    display.sleep();
                }
            }
        }
    }

    private class DialogAddCard {

        private Text nameInput, attackInput, defenseInput;
        private Label name, attack, defense;
        private Button button;
        private boolean isNewCard;

        private void initDialogAddCard(Shell shell, Display display) {
            shell.setLayout(new GridLayout(6, false));
            name = new Label(shell, SWT.NULL);
            name.setText("Card name:");
            nameInput = new Text(shell, SWT.SINGLE | SWT.BORDER);
            nameInput.setTextLimit(30);
            nameInput.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
            attack = new Label(shell, SWT.NULL);
            attack.setText("Attack:");
            attackInput = new Text(shell, SWT.SINGLE | SWT.BORDER);
            attackInput.setTextLimit(30);
            attackInput.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
            defense = new Label(shell, SWT.NULL);
            defense.setText("Defense:");
            defenseInput = new Text(shell, SWT.SINGLE | SWT.BORDER);
            defenseInput.setTextLimit(30);
            defenseInput.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
            this.button = new Button(shell, SWT.PUSH);
            button.setText("Submit");
        }

        private void addButtonListener(final Shell shell, final int index) {
            button.addSelectionListener(new SelectionListener() {

                public void widgetSelected(SelectionEvent e) {
                    final String name = nameInput.getText();
                    final String atk = attackInput.getText();
                    final String defense = defenseInput.getText();
                    if (!name.isEmpty() && !atk.isEmpty() && !defense.isEmpty()) {
                        boolean chkName = containsRealTextInput(name);
                        boolean chkAtk = isStringANumber(atk);
                        boolean chkDefense = isStringANumber(defense);
                        if (chkName && chkAtk && chkDefense) {
                            Integer attackInt = Integer.parseInt(atk);
                            Integer defInt = Integer.parseInt(defense);
                            if (!isNumberInAttackRange(attackInt)) {
                                showError(shell, "Attack field of '" + name + "' isn't within legal bounds, "
                                        + ATTACK_MIN + "<=num<=" + ATTACK_MAX);
                            } else if (!isNumberInDefenseRange(defInt)) {
                                showError(shell, "Defense field of '" + name + "' isn't within legal bounds, "
                                        + DEFENSE_MIN + "<=num<=" + DEFENSE_MAX);
                            } else {
                            	shell.getDisplay().asyncExec(new Runnable(){
                            		public void run(){
                            			 if (isNewCard) {
                                             addCardButtonLogic(name, atk, defense);
                                         } else {
                                             saveChangesToTable(name, atk, defense, index);
                                         }
                                         shell.close();
                            		}
                            	});
                               
                            }
                        } else {
                            if (!chkName) {
                                showError(shell, "Name contains only whitespaces!");
                            } else if (!chkAtk) {
                                showError(shell, "Attack field doesn't contain an integer");
                            } else {
                                showError(shell, "Defense field doesn't contain an integer");
                            }
                        }
                    } else {
                        showError(shell, "Please fillout all the fields");
                    }
                }

                public void widgetDefaultSelected(SelectionEvent e) {
                }
            });
        }

        private DialogAddCard(String name, String attack, String defense, int index) {
            Display display = shell.getDisplay();
            final Shell shell = new Shell(display);
            shell.setText("View and Edit Card");
            initDialogAddCard(shell, display);
            nameInput.setText(name);
            attackInput.setText(attack);
            defenseInput.setText(defense);
            this.isNewCard = false;
            button.setToolTipText("Click to save changes");
            addButtonListener(shell, index);
            shell.pack();
            shell.open();
            while (!shell.isDisposed()) {
                if (!display.readAndDispatch()) {
                    display.sleep();
                }
            }
        }

        private DialogAddCard() {
            Display display = shell.getDisplay();
            final Shell shell = new Shell(display);
            shell.setText("Add Card");
            initDialogAddCard(shell, display);
            nameInput.setText("");
            attackInput.setText("");
            defenseInput.setText("");
            this.isNewCard = true;
            button.setToolTipText("Click to add Card");
            addButtonListener(shell, -1);
            shell.pack();
            shell.open();
            while (!shell.isDisposed()) {
                if (!display.readAndDispatch()) {
                    display.sleep();
                }
            }
        }
    }

    
    public static void main(String[] args) {
    	
    	DBManager.DB_CONNECTION_STRING = args[0];
    	DBManager.DB_USER_NAME = args[1];
    	DBManager.DB_PASSWORD = args[2];
    	ConnectionPool.numberOfConnections = Integer.parseInt(args[3]);
    	UniverseConcrete.entriesPerPage = Integer.parseInt(args[4]);
    	ServerGUI.universesPerDisplay = Integer.parseInt(args[5]);
    	UsersGui.usersToDisplay = Integer.parseInt(args[6]);
    	
    	ServerGUI.characterDump = args[7];
    	ServerGUI.universeDump = args[8];
    	
        Display display = new Display();
        Shell shell = new Shell(display, SWT.MENU);
        new ServerGUI(shell);
        shell.open();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
    }
    
     
}